﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetworkAssetManager.Entity;
using System.Management;
using log4net;

namespace NetworkAssetManager.WMI
{
    class Computer
    {
        private static readonly ILog _logger = LogManager.GetLogger(typeof(Computer));
        public enum DomainRoleValues
        {
            StandaloneWorkstation,
            MemberWorkstation,
            StandaloneServer,
            MemberServer,
            BackupDomainController,
            PrimaryDomainController
        }
        public enum PCSystemTypeValues
        {
             Unspecified,
             Desktop,
             Mobile,
             Workstation,
             EnterpriseServer,
             SmallOfficeAndHomeOfficeServer,
             AppliancePC,
             PerformanceServer,
             Maximum
        }

        public enum PowerStateValues
        {
            Unknown,
            FullPower,
            PowerSaveLowPowerMode,
            PowerSaveStandby, 
            PowerSaveUnknown,
            PowerCycle,
            PowerOff,
            PowerSaveWarning
        }
        public enum StateValues
        {
            Other,
            Unknown,
            Safe,
            Warning,
            Critical,
            Nonrecoverable
        }

        public enum WakeupTypeValues
        {
            Reserved,
            Other,
            Unknown,
            APMTimer,
            ModemRing,
            LANRemote,
            PowerSwitch,
            PCIPME,
            ACPowerRestored
        }

        private static EntComputer FillDetails(ManagementBaseObject obj)
        {
            EntComputer objEntComp = new EntComputer();

            try
            {
                objEntComp.BootupState = WMIUtil.ToString(obj["BootupState"]);
            }
            catch (Exception)
            {
                objEntComp.BootupState = "";
            }

            try
            {
                objEntComp.Caption = WMIUtil.ToString(obj["Caption"]);
            }
            catch (Exception)
            {
                objEntComp.Caption = "";
            }

            try
            {
                int timeZone = WMIUtil.ToInteger(obj["CurrentTimeZone"]); 
                if ( timeZone < 0 )
                {
                    objEntComp.CurrentTimeZone = "GMT -" + timeZone.ToString()+" minutes";
                }
                else
                {
                    objEntComp.CurrentTimeZone = "GMT +" + timeZone.ToString()+" minutes";
                }
            }
            catch (Exception)
            {
                objEntComp.CurrentTimeZone = "";
            }

            try
            {
                objEntComp.DaylightInEffect = (bool)obj["DaylightInEffect"]; 
            }
            catch (Exception)
            {
                objEntComp.DaylightInEffect= false;
            }

            try
            {
                objEntComp.Description = WMIUtil.ToString(obj["Description"]);
            }
            catch (Exception)
            {
                objEntComp.Description = "";
            }

            try
            {
                objEntComp.DNSHostName = WMIUtil.ToString(obj["DNSHostName"]);
            }
            catch (Exception)
            {
                objEntComp.DNSHostName = "N/A";
            }

            try
            {
                objEntComp.Domain = WMIUtil.ToString(obj["Domain"]);
            }
            catch (Exception)
            {
                objEntComp.Domain = "";
            }

            try
            {
                DomainRoleValues domainRoles = (DomainRoleValues)WMIUtil.ToInteger(obj["DomainRole"]);
                objEntComp.DomainRole = WMIUtil.SplitCamelCase(domainRoles.ToString());
            }
            catch (Exception)
            {
                objEntComp.DomainRole = "";
            }

            try
            {
                objEntComp.EnableDaylightSavingsTime = (bool)obj["EnableDaylightSavingsTime"]; 
            }
            catch (Exception)
            {
                objEntComp.EnableDaylightSavingsTime = false; 
            }

            try
            {
                objEntComp.Manufacturer = WMIUtil.ToString(obj["Manufacturer"]); 
            }
            catch (Exception)
            {
                objEntComp.Manufacturer = "";
            }

            try
            {
                objEntComp.Model = WMIUtil.ToString(obj["Model"]);
            }
            catch (Exception)
            {
                objEntComp.Model = "";
            }

            try
            {
                objEntComp.Name = WMIUtil.ToString(obj["Name"]);
            }
            catch (Exception)
            {
                objEntComp.Name = "";
            }

            try
            {
                objEntComp.NetworkServerModeEnabled = (bool)(obj["NetworkServerModeEnabled"]);
            }
            catch (Exception)
            {
                objEntComp.NetworkServerModeEnabled = false;
            }

            try
            {
                objEntComp.PartOfDomain = (bool)(obj["PartOfDomain"]);
            }
            catch (Exception)
            {
                objEntComp.PartOfDomain = false;
            }

            try
            {
                PCSystemTypeValues pcTypeValues = (PCSystemTypeValues)WMIUtil.ToInteger(obj["PCSystemType"]);
                objEntComp.PCSystemType = WMIUtil.SplitCamelCase(pcTypeValues.ToString());
            }
            catch (Exception)
            {
                objEntComp.PCSystemType = "Unknown";
            }

            try
            {
                PowerStateValues powerStateValues = (PowerStateValues)WMIUtil.ToInteger(obj["PowerState"]);
                objEntComp.PowerState = WMIUtil.SplitCamelCase(powerStateValues.ToString());
            }
            catch (Exception)
            {
                objEntComp.PowerState = "";
            }

            try
            {
                StateValues powerSupplyStateValues = (StateValues)WMIUtil.ToInteger(obj["PowerState"]);
                objEntComp.PowerSupplyState= WMIUtil.SplitCamelCase(powerSupplyStateValues.ToString());
            }
            catch (Exception)
            {
                objEntComp.PowerSupplyState = "";
            }

            try
            {
                objEntComp.PrimaryOwnerContact = WMIUtil.ToString(obj["PrimaryOwnerContact"]);
            }
            catch (Exception)
            {
                objEntComp.PrimaryOwnerContact = "";
            }

            try
            {
                objEntComp.PrimaryOwnerName = WMIUtil.ToString(obj["PrimaryOwnerName"]);
            }
            catch (Exception)
            {
                objEntComp.PrimaryOwnerName = "";
            }

            try
            {
                objEntComp.Roles = WMIUtil.StringArrayToString(obj["Roles"]);
            }
            catch (Exception)
            {
                objEntComp.Roles = ""; 
            }

            try
            {
                objEntComp.Status = WMIUtil.ToString(obj["Status"]);
            }
            catch (Exception)
            {
                objEntComp.Status = "";
            }

            try
            {
                objEntComp.SupportContactDescription = WMIUtil.ToString(obj["SupportContactDescription"]);
            }
            catch (Exception)
            {
                objEntComp.SupportContactDescription = "";
            }

            try
            {
                objEntComp.SystemStartupDelay = WMIUtil.ToInteger(obj["SystemStartupDelay"]);
            }
            catch (Exception)
            {
                objEntComp.SystemStartupDelay = -1;
            }

            try
            {
                objEntComp.SystemStartupOptions = WMIUtil.StringArrayToString(obj["SystemStartupOptions"]);
            }
            catch (Exception)
            {
                objEntComp.SystemStartupOptions = "";
            }

            try
            {
                objEntComp.SystemType = WMIUtil.ToString(obj["SystemType"]);
            }
            catch (Exception)
            {
                objEntComp.SystemType = "";
            }

            try
            {
                StateValues thermalStateValues = (StateValues)WMIUtil.ToInteger(obj["PowerState"]);
                objEntComp.ThermalState = WMIUtil.SplitCamelCase(thermalStateValues.ToString());
            }
            catch (Exception)
            {
                objEntComp.ThermalState = "";
            }

            try
            {
                objEntComp.UserName = WMIUtil.ToString(obj["UserName"]);
            }
            catch (Exception)
            {
                objEntComp.UserName = "";
            }

            try
            {
                WakeupTypeValues wakeUpValues = (WakeupTypeValues)WMIUtil.ToInteger(obj["WakeUpType"]);
                objEntComp.WakeUpType = WMIUtil.SplitCamelCase(wakeUpValues.ToString());
            }
            catch (Exception)
            {
                objEntComp.WakeUpType = "";
            }

            try
            {
                objEntComp.Workgroup = WMIUtil.ToString(obj["Workgroup"]);
            }
            catch (Exception)
            {
                objEntComp.Workgroup = "";
            }

            return objEntComp; 
        }
        public static List<EntComputer>GetComputerDetails(ManagementScope scope)
        {
            _logger.Info("Collecting Computer details for machine " + scope.Path.Server);

            ObjectQuery query = null;
            ManagementObjectSearcher searcher = null;
            ManagementObjectCollection objects = null;
            List<EntComputer> lstComp = new List<EntComputer>();

            try
            {
                query = new ObjectQuery("Select * from Win32_ComputerSystem");
                searcher = new ManagementObjectSearcher(scope, query);
                objects = searcher.Get();
                lstComp.Capacity = objects.Count;
                foreach (ManagementBaseObject obj in objects)
                {
                    lstComp.Add(FillDetails(obj));
                    obj.Dispose();
                }

            }
            catch (System.Exception e)
            {
                _logger.Error("Exception is Computer information collection " + e.Message);
            }
            finally
            {
                searcher.Dispose();
            }
            return lstComp;
        }

    }
}
